#ifndef __BOTTOM_CANFD_H_
#define __BOTTOM_CANFD_H_

#include "stm32h7xx.h"
#include "stm32_types.h"
#include "stm32h7xx_hal.h"

extern FDCAN_HandleTypeDef hfdcan1;

/*	上位机发送给板子的查询指令	*/
#define MOTOT_HOSTCOMPUTER	0X100
/*	板子给上位机的查询指令	*/
#define MOTOT_COMPUTERHOST	0X150

/*电机心跳基地址	*/
#define MOTOT_HEART_BASE	0x700
/*电机寄存器查询回复	*/
#define MOTOR_REGISTER_RES 0x580

/*电机自动回传 实际位置 + 状态字 */
#define MOTOT_TPD01_BASE 	0x180
/*实际位置 + 实际速度*/
#define MOTOT_TPD03_BASE 	0x380

/*	电机1号.偏移地址	*/
#define MOTOT_ID1				1
/*	电机2号.偏移地址	*/
#define MOTOT_ID2				2
/*	电机3号.偏移地址	*/
#define MOTOT_ID3				3
/*	电机4号.偏移地址	*/
#define MOTOT_ID4				4	

#define CAN_MSG_BUFFERSIZE 8

typedef struct{
  uint8_t  recv_msg_flag;
  uint8_t  recv_msg_len;
  uint8_t  *msg_buffer_user;
  uint8_t  *msg_buffer_recv;
  uint8_t  msg_buffer_1[CAN_MSG_BUFFERSIZE];
  uint8_t  msg_buffer_2[CAN_MSG_BUFFERSIZE];
  uint32_t standard_id;
}CanRecvMessage;

extern CanRecvMessage user_can_recv_msg;

void hw_canopen_can_init(void);
void hw_user_can_init(void);
void canopen_can_send_msg(uint32_t id,uint8_t *pbuf,uint8_t len);
void user_can_send_msg(uint32_t id,uint8_t *pbuf,uint8_t len);





////////////////////////////////////CAN1///////////////////////////////
#define CAN1_CLK_ENABLE()               __HAL_RCC_CAN1_CLK_ENABLE()
#define CAN1_GPIO_CLK_ENABLE()          __HAL_RCC_GPIOA_CLK_ENABLE()

#define CAN1_FORCE_RESET()              __HAL_RCC_CAN1_FORCE_RESET()
#define CAN1_RELEASE_RESET()            __HAL_RCC_CAN1_RELEASE_RESET()

//管脚定义
#define CAN1_TX_PIN                    GPIO_PIN_12
#define CAN1_TX_GPIO_PORT              GPIOA
#define CAN1_TX_AF                     GPIO_AF9_CAN1
#define CAN1_RX_PIN                    GPIO_PIN_11
#define CAN1_RX_GPIO_PORT              GPIOA
#define CAN1_RX_AF                     GPIO_AF9_CAN1

#define CAN1_RX_IRQn                   CAN1_RX0_IRQn
#define CAN1_RX_IRQHandler             CAN1_RX0_IRQHandler

#define FDCANx                      FDCAN1
#define FDCANx_CLK_ENABLE()         __HAL_RCC_FDCAN_CLK_ENABLE()
#define FDCANx_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define FDCANx_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()

#define FDCANx_FORCE_RESET()   __HAL_RCC_FDCAN_FORCE_RESET()
#define FDCANx_RELEASE_RESET() __HAL_RCC_FDCAN_RELEASE_RESET()

/* Definition for FDCANx Pins */    
#define FDCANx_TX_PIN       GPIO_PIN_12
#define FDCANx_TX_GPIO_PORT GPIOA
#define FDCANx_TX_AF        GPIO_AF9_FDCAN1
#define FDCANx_RX_PIN       GPIO_PIN_11
#define FDCANx_RX_GPIO_PORT GPIOA
#define FDCANx_RX_AF        GPIO_AF9_FDCAN1

/* Definition for FDCANx's NVIC IRQ and IRQ Handlers */
#define FDCANx_IT0_IRQn   FDCAN1_IT0_IRQn
#define FDCANx_IT1_IRQn   FDCAN1_IT1_IRQn
#define FDCANx_IRQHandler FDCAN1_IRQHandler

///////////////////////////////////CAN2////////////////////////////////////
#define CAN2_CLK_ENABLE()               __HAL_RCC_CAN2_CLK_ENABLE()
#define CAN2_GPIO_CLK_ENABLE()          __HAL_RCC_GPIOB_CLK_ENABLE()

#define CAN2_FORCE_RESET()              __HAL_RCC_CAN2_FORCE_RESET()
#define CAN2_RELEASE_RESET()            __HAL_RCC_CAN2_RELEASE_RESET()

//管脚定义
#define CAN2_TX_PIN                    GPIO_PIN_6
#define CAN2_TX_GPIO_PORT              GPIOB
#define CAN2_TX_AF                     GPIO_AF9_CAN2
#define CAN2_RX_PIN                    GPIO_PIN_5
#define CAN2_RX_GPIO_PORT              GPIOB
#define CAN2_RX_AF                     GPIO_AF9_CAN2

#define CAN2_RX_IRQn                   CAN2_RX1_IRQn
#define CAN2_RX_IRQHandler             CAN2_RX1_IRQHandler

// CAN Default IDs and Filter Masks
#define CAN1_DEFAULT_ID         0x111
#define CAN2_DEFAULT_ID         0x222
#define CAN_FILTER_MASK         0x7FF

// Default Data Timing Parameters
#define CAN_DEFAULT_DATA_SJW    0x4
#define CAN_DEFAULT_DATA_TS1    0x5
#define CAN_DEFAULT_DATA_TS2    0x4

// CAN Mode Definitions
typedef enum {
    CAN_MODE_NORMAL,
    CAN_MODE_LOOPBACK
} CAN_ModeTypeDef;

// CAN Frame Format Definitions
typedef enum {
    CAN_FRAME_CLASSIC,
    CAN_FRAME_FD_BRS
} CAN_FrameFormatTypeDef;

typedef struct  
{
    u32 MsgID;                 // ID:标准ID(11位)/扩展ID(11位+18位)	 
    u8  *data;               // 数据缓存
    u8  len;                   // 要发送的数据长度
    u8  format;                // 0 - 标准帧, 1- 扩展帧
    u8  type;                  // 0 - 数据帧, 1 - 远程帧
} CAN_msg;

// External Declarations
extern FDCAN_HandleTypeDef Can1Handle;
extern FDCAN_HandleTypeDef Can2Handle;
extern CAN_msg CAN1_RxMsg;
extern CAN_msg CAN2_RxMsg;
extern uint16_t CAN1_RxRdy;
extern uint16_t CAN2_RxRdy;
        
extern CAN_msg  CAN1_TxMsg;
                                                   
// Function Prototypes
void FDCAN1_Init(CAN_ModeTypeDef Mode, uint32_t tsjw, uint32_t tbs1, uint32_t tbs2, uint16_t brp);
void FDCAN2_Init(CAN_ModeTypeDef Mode, uint32_t tsjw, uint32_t tbs1, uint32_t tbs2, uint16_t brp);
void FDCAN_SendMessage(FDCAN_HandleTypeDef *hfdcan, uint32_t id, uint8_t *buff, uint32_t len);

/*******************************************************************************
* Function Name  : CAN1_Init
* Description    : CAN1初始化,主CAN
* Input          : Mode:工作模式
				   CAN_MODE_NORMAL  正常通信模式  
                   CAN_MODE_LOOPBACK  回环通信模式
				   tsjw:重新同步跳跃时间单元.范围:CAN_SJW_1TQ~CAN_SJW_4TQ
				   tbs1:时间段1的时间单元.   范围:CAN_BS1_1TQ~CAN_BS1_16TQ
				   tbs2:时间段2的时间单元.   范围:CAN_BS2_1TQ~CAN_BS2_8TQ		   
				   brp :波特率分频器.范围:1~1024; tq=(brp)*tpclk1
				   波特率=Fpclk1/((tbs1+1+tbs2+1+1)*brp),Fpclk1=42MHz
* Output         : None
* Return         : None
* Note			 : 波特率计算示例
				   tsjw = CAN_SJW_1TQ
				   tbs1 = CAN_BS1_14TQ
				   tbs2 = CAN_BS2_6TQ
				   brp = 4
				   则波特率 = 42M/((1+6+14)*4) = 500KHz
*******************************************************************************/
void CAN1_Init(uint8_t *Rx_Buff, uint32_t Mode, uint32_t tsjw, uint32_t tbs1, uint32_t tbs2, uint16_t brp);

/*******************************************************************************
* Function Name  : CAN2_Init
* Description    : CAN2初始化,从CAN,共享CAN1资源,需要开启CAN1
* Input          : Mode:工作模式
				   CAN_MODE_NORMAL  正常通信模式  
                   CAN_MODE_LOOPBACK  回环通信模式
				   tsjw:重新同步跳跃时间单元.范围:CAN_SJW_1TQ~CAN_SJW_4TQ
				   tbs1:时间段1的时间单元.   范围:CAN_BS1_1TQ~CAN_BS1_16TQ
				   tbs2:时间段2的时间单元.   范围:CAN_BS2_1TQ~CAN_BS2_8TQ		   
				   brp :波特率分频器.范围:1~1024; tq=(brp)*tpclk1
				   波特率=Fpclk1/((tbs1+1+tbs2+1+1)*brp),Fpclk1=42MHz
* Output         : None
* Return         : None
* Note			 : 波特率计算示例
				   tsjw = CAN_SJW_1TQ
				   tbs1 = CAN_BS1_14TQ
				   tbs2 = CAN_BS2_6TQ
				   brp = 4
				   则波特率 = 42M/((1+6+14)*4) = 500KHz
*******************************************************************************/
void CAN2_Init(uint32_t Mode, uint32_t tsjw, uint32_t tbs1, uint32_t tbs2, uint16_t brp);

/*******************************************************************************
* Function Name  : CAN_TX_Msg
* Description    : CAN数据发送
* Input          : CanHandle   CAN句柄
				   msg  CAN消息结构体  
* Output         : None
* Return         : None
* Note			 : None
*******************************************************************************/
void CAN_TX_Msg(uint8_t *buff, uint32_t len);

/*******************************************************************************
* Function Name  : CAN_RX_Msg
* Description    : CAN数据接收
* Input          : CanHandle   CAN句柄
				   msg  CAN消息结构体  
* Output         : None
* Return         : None
* Note			 : None
*******************************************************************************/
void CAN_RX_Msg(FDCAN_HandleTypeDef *CanHandle, CAN_msg *msg);

#endif

